package com.webcamtracker;

import com.webcamtracker.color.SegmentationTrackingObjectFinder;
import com.webcamtracker.color.segmentation.BlurPreProcessor;
import com.webcamtracker.color.segmentation.ColorSegmentator;
import com.webcamtracker.color.segmentation.HSVColorPlannerPreProcessor;
import com.webcamtracker.color.segmentation.PreProcessor;
import com.webcamtracker.color.segmentation.Segment;
import com.webcamtracker.color.segmentation.SegmentationImageTracker;
import com.webcamtracker.image.Color;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;

/**
 * Created by IntelliJ IDEA.
 * User: machaval
 * Date: Mar 11, 2008
 * Time: 7:44:13 PM
 * To change this template use File | Settings | File Templates.
 */
public class Test {
    private static final String IMAGE_PATH = "/home/machaval/work/webcamtracker/tracker/img/Colores.png";

    public static void main(String[] args) throws IOException {
//        test();
//        test1();
        //   testListAddPerformance();

//        testZoomFactor();

        testHsvColorPlanner();

    }

    private static void testZoomFactor() {
        Segment a = new Segment(1, 4);
        Segment b = new Segment(6, 16);
        final float zoom = SegmentationImageTracker.getZoom(a, b);
        System.out.println("zoom = " + zoom);
        final float zoom1 = SegmentationImageTracker.getZoom(b, a);
        System.out.println("zoom1 = " + zoom1);
    }

    private static void testListAddPerformance() {
        List<Object> arrayList = new ArrayList<Object>();
        List<Object> linkedList = new LinkedList<Object>();

        final int testSize = 10000000;
        Object o = new Object();
        long start1 = System.currentTimeMillis();
        for (int i = 0; i < testSize; i++) {
            linkedList.add(o);
        }
        long end1 = System.currentTimeMillis();
        System.out.println("Tardo Linked List = " + (end1 - start1));

        long start0 = System.currentTimeMillis();
        for (int i = 0; i < testSize; i++) {
            arrayList.add(0);
        }
        long end0 = System.currentTimeMillis();
        System.out.println("Tardo ArrayList = " + (end0 - start0));


    }

    private static void test1() {
        int i = 0;

        double h;

        final int x = 3;

        float hue;

        h = 0.9;
        calculate(h, x);
        h = 0.7;
        calculate(h, x);
        h = 0.5;
        calculate(h, x);
        h = 0.4;
        calculate(h, x);
        h = 0.3;
        calculate(h, x);
        h = 0.01;
        calculate(h, x);
    }

    public static void testHsvColorPlanner() throws IOException {

        File file = new File(IMAGE_PATH);
        final Image image = ImageIO.read(file);
        final JFrame jFrame = new JFrame();
        JPanel panel = new JPanel();
        JPanel panel2 = new JPanel();
        ImageIcon icon = new ImageIcon(IMAGE_PATH);
        Image image2 = icon.getImage();

    // Create empty BufferedImage, sized to Image
    BufferedImage buffImage =
      new BufferedImage(
          image.getWidth(null),
          image.getHeight(null),
          BufferedImage.TYPE_INT_ARGB);

    // Draw Image into BufferedImage
    Graphics g = buffImage.getGraphics();
    g.drawImage(image2, 0, 0, null);

        final BufferedImage processedImage =new BlurPreProcessor().process(buffImage);
        final Canvas canvas;
        canvas = new Canvas() {
            public Dimension getPreferredSize() {
                return new Dimension(image.getWidth(null), image.getHeight(null));
            }

            public boolean isDoubleBuffered() {
                return true;
            }

            public void paint(Graphics g) {
                g.drawImage(image, 0, 0, null);
            }
        };
        Canvas processed = new Canvas() {
            public Dimension getPreferredSize() {
                return new Dimension(image.getWidth(null), image.getHeight(null));
            }

            public boolean isDoubleBuffered() {
                return true;
            }

            public void paint(Graphics g) {
                g.drawImage(processedImage, 0, 0, null);
            }
        };
        panel.add(canvas);
        panel2.add(processed);
        final Container contentPane = jFrame.getContentPane();
        contentPane.setLayout(new FlowLayout());
        contentPane.add(panel);
        contentPane.add(panel2);

        jFrame.pack();
        jFrame.setVisible(true);
    }

    public static void test() {
        List<PreProcessor> preprocessors = Arrays.asList(new BlurPreProcessor(), new HSVColorPlannerPreProcessor());
        SegmentationTrackingObjectFinder segmentator = new SegmentationTrackingObjectFinder();

        BufferedImage image = loadImage(IMAGE_PATH);
        long start0 = System.currentTimeMillis();
        for (PreProcessor preprocessor : preprocessors) {
            image = preprocessor.process(image);
        }
        long end0 = System.currentTimeMillis();
        System.out.println("Tardo Pre Processors = " + (end0 - start0));


        final long start1 = System.currentTimeMillis();
        final Map<Color, SortedSet<Segment>> map = segmentator.segment(image);
        final long end1 = System.currentTimeMillis();
        long tacke1 = (end1 - start1);
        System.out.println("Tardo SegmentationTrackingObject = " + tacke1);


        ColorSegmentator segmentator2 = new ColorSegmentator();
        BufferedImage image2 = loadImage(IMAGE_PATH);
        for (PreProcessor preprocessor : preprocessors) {
            image2 = preprocessor.process(image2);
        }

        long start2 = System.currentTimeMillis();
        final Map<Color, SortedSet<Segment>> map2 = segmentator2.segment(image);
        long end2 = System.currentTimeMillis();
        long tacke2 = (end2 - start2);
        System.out.println("Tardo Segmentator = " + tacke2);


        Set<Map.Entry<Color, SortedSet<Segment>>> entries = map.entrySet();
        for (Map.Entry<Color, SortedSet<Segment>> entry : entries) {
            SortedSet<Segment> value = entry.getValue();
            SortedSet<Segment> set = map2.get(entry.getKey());
            if (value.size() != set.size()) {
                System.out.println("Son distintos " + entry.getKey());
            }
            Iterator<Segment> iterator = value.iterator();
            for (Segment segment : set) {
                Segment segment1 = iterator.next();
                if (segment1.getSize() != segment.getSize()) {
                    System.out.println("Son distintos " + entry.getKey());
                }
            }
        }
    }

    private static void calculate(double h, int x) {
        float hue = (float) (Math.floor(h * (x)) * 1 / x);
        System.out.println("hue = " + hue);
    }

    private static final String JPG = "jpg";

    // This method returns a buffered image with the contents of an image
    public static BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        }

        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();

        // Determine if the image has transparent pixels; for this method's
        // implementation, see e661 Determining If an Image Has Transparent Pixels
        boolean hasAlpha = hasAlpha(image);

        // Create a buffered image with a format that's compatible with the screen
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try {
            // Determine the type of transparency of the new buffered image
            int transparency = Transparency.OPAQUE;
            if (hasAlpha) {
                transparency = Transparency.BITMASK;
            }

            // Create the buffered image
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(
                    image.getWidth(null), image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        }

        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            if (hasAlpha) {
                type = BufferedImage.TYPE_INT_ARGB;
            }
            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
        }

        // Copy image to buffered image
        Graphics g = bimage.createGraphics();

        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();

        return bimage;
    }

    public static BufferedImage clone(BufferedImage toClone) {
        PixelGrabber pg = new PixelGrabber(toClone, 0, 0, -1, -1, true);

        try {
            pg.grabPixels();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        int[] raster = (int[]) pg.getPixels();


        MemoryImageSource memoryimagesource =
                new MemoryImageSource(pg.getWidth(), pg.getHeight(), raster, 0, pg.getWidth());
        return toBufferedImage(Toolkit.getDefaultToolkit().createImage(memoryimagesource));

    }

    public static boolean hasAlpha(Image image) {
        // If buffered image, the color model is readily available
        if (image instanceof BufferedImage) {
            BufferedImage bimage = (BufferedImage) image;
            return bimage.getColorModel().hasAlpha();
        }

        // Use a pixel grabber to retrieve the image's color model;
        // grabbing a single pixel is usually sufficient
        PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
        try {
            pg.grabPixels();
        } catch (InterruptedException e) {
        }

        // Get the image's color model
        ColorModel cm = pg.getColorModel();
        return cm.hasAlpha();
    }

    public static void storeImage(BufferedImage image, String id) {
        // Write generated image to a file
        try {
            // Save as JPEG
            File file = new File(id + "." + JPG);
            ImageIO.write(image, JPG, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Returns a generated image.
    }

    public static BufferedImage loadImage(String path) {
        Image image = null;
        try {
            // Read from a file
            File file = new File(path);
            image = ImageIO.read(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return toBufferedImage(image);
    }
}
